﻿using System;
using System.Buffers;
using System.IO;
using System.Net.Security;
using System.Threading.Tasks;
using Deer.Extension;
using Letter.IO.Binary;
using Letter.Net.Tcp;

namespace Telex;

sealed class RpcClientConnection : ARcpConnection
{
    public RpcClientConnection(ref ConnectionFixedConfig config, TaskCompletionSource<RpcHost> tcs) : base(ref config)
    {
        this.tcs = tcs;
    }

    public RpcClientConnection(ref ConnectionFixedConfig config, SslOptions sslOptions, Func<Stream, SslStream> sslStreamFactory, TaskCompletionSource<RpcHost> tcs)
        : base(ref config, sslOptions, sslStreamFactory)
    {
        this.tcs = tcs;
    }

    private TaskCompletionSource<RpcHost> tcs;
    
    protected override void OnActive()
    {
        base.OnActive();
        this.Pipelines.Output.DeliverSecretkeyReqPack(this.secretkey);
    }

    protected override void OnMessage(ReadOnlySequence<byte> buf)
    {
        var reader = buf.ToBytesReader();
        var command = reader.ReadUInt8();
        switch (command)
        {
            case Command.SECRET_KEY_RES:
                this.OnRcvSecretkeyResMessage(ref reader);
                break;
            case Command.SYNC_HOST_OPTIONS:
                this.OnRcvSyncHost(ref reader);
                break;
            default:
                this.OnRcvSocketMessage(command, ref reader);
                break;
        }
    }

    private void OnRcvSecretkeyResMessage(ref BytesReader reader)
    {
        var status = reader.ReadUInt8();
        if (status == 1)
        {
            this.Pipelines.Output.DeliverHostOptions(this.localHost);
        }
        else
        {
            this.CloseAsync().Sync();
        }
    }

    protected override void OnRcvSyncHost(ref BytesReader reader)
    {
        base.OnRcvSyncHost(ref reader);
        tcs.SetResult(this.remoteHost);
    }
}